/**
 * \file FileSystem.h
 * \brief File system facilities
 * \author Corey Tabaka
 */

/*
   Copyright 2007 Corey Tabaka

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include <ktypes.h>
#include <Reference.h>

#ifndef __KERNEL_FILESYSTEM_H__
#define __KERNEL_FILESYSTEM_H__

class IFileSystem;
DEF_REF_TYPE(IFileSystem);

class IFSNode;
DEF_REF_TYPE(IFSNode);

class IDirectory;
DEF_REF_TYPE(IDirectory);

class IFile;
DEF_REF_TYPE(IFile);

class IBlock;
DEF_REF_TYPE(IBlock);


/*
 * FileSystem
 *
 * Filesystem interface
 */
class IFileSystem {
	public:
	
	virtual ~IFileSystem(void) {}
	
	virtual RefIDirectory getRoot(void) = 0;
};

/*
 * IFSNode
 *
 * Base class of heirarchy nodes (IDirectory, IFile, etc)
 */
typedef enum {
	IFS_TYPE_NONE=0,
	IFS_TYPE_DIR,
	IFS_TYPE_FILE,
	IFS_TYPE_BLOCK,
	IFS_TYPE_STREAM,
} ifs_type_e;

class IFSNode {
	public:
	
	virtual ~IFSNode(void) {}
	
	virtual const char *getName(void) = 0;
	virtual ifs_type_e getType(void) = 0;
};
	
/*
 * IDirectory Interface
 *
 * Abstract interface to directory style hierarchy
 */
class IDirectory : public IFSNode {
	public:
	
	virtual ~IDirectory(void) {}
	
	// from IFSNode
	virtual const char *getName(void) = 0;
	virtual ifs_type_e getType(void) { return IFS_TYPE_DIR; }
	
	virtual RefIDirectory getParent(void) = 0;
	virtual int getNumChildren(void) = 0;
	virtual RefIFSNode getChild(unsigned int i) = 0;
	
	virtual bool isRoot(void) = 0;
};

/*
 * IFile Interface
 *
 * Abstract interface to file nodes
 */
class IFile : public IFSNode {
	public:
	
	virtual ~IFile(void) {}
	
	// from IFSNode
	virtual const char *getName(void) = 0;
	virtual ifs_type_e getType(void) { return IFS_TYPE_FILE; }
	
	virtual unsigned long long getSize(void) = 0;
	
	virtual int read(char *buf, unsigned int len) = 0;
	virtual int write(const char *buf, unsigned int len) = 0;
	
	virtual int seek(unsigned long long pos) = 0;
	virtual long long tell(void) = 0;
	
	virtual int param(int key, int val) = 0;
};

/*
 * IBlock Interface
 *
 * Abstract interface to block device nodes
 */
class IBlock : public IFSNode {
	public:
	
	virtual ~IBlock(void) {}
	
	// from IFSNode
	virtual const char *getName(void) = 0;
	virtual ifs_type_e getType(void) { return IFS_TYPE_BLOCK; }
	
	virtual unsigned long long getBlockCount(void) = 0;
	virtual unsigned int getBlockSize(void) = 0;
	
	virtual int readBlocks(char *buffer, unsigned int count) = 0;
	virtual int writeBlocks(const char *buffer, unsigned int count) = 0;
	
	virtual int seekBlock(unsigned long long block) = 0;
	virtual long long tellBlock(void) = 0;
};

/*
 * File access flags
 */
enum {
	IFILE_READ=0x01,
	IFILE_WRITE=0x02,
	IFILE_SHARE_READ=0x04,
	IFILE_SHARE_WRITE=0x08,
};

#endif

#endif
